package com.postgresql.geoserver;

import it.geosolutions.geoserver.rest.GeoServerRESTPublisher;
import it.geosolutions.geoserver.rest.HTTPUtils;
import it.geosolutions.geoserver.rest.encoder.GSLayerEncoder;
import it.geosolutions.geoserver.rest.encoder.feature.GSFeatureTypeEncoder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author: 顾志杰
 */
public class GeoServerRESTPublisherEx extends GeoServerRESTPublisher {
    /** The logger for this class */
    private static final Logger LOGGER = LoggerFactory.getLogger(GeoServerRESTPublisherEx.class);

    private String restURL;

    private  String gsuser;

    private  String gspass;


    /**
     * Creates a <TT>GeoServerRESTPublisher</TT> to connect against a GeoServer instance with the given URL and user credentials.
     *
     * @param restURL  the base GeoServer URL (e.g.: <TT>http://localhost:8080/geoserver</TT>)
     * @param username auth credential
     * @param password auth credential
     */
    public GeoServerRESTPublisherEx(String restURL, String username, String password) {
        super(restURL, username, username);
        this.restURL = HTTPUtils.decurtSlash(restURL);
        this.gsuser = username;
        this.gspass = password;
    }

    /**
     * Publish and configure a new layer from an existing DataStore (v. gr. a layer from a DB table).
     *
     * @param workspace Workspace name where DataStore is.
     * @param storename DataStore name.
     * @param fte FeatureType configuration details using a {@link GSFeatureTypeEncoder}.
     * @return {@code true} if layer is successfully created.
     */

    public String publishDBLayerStr(final String workspace, final String storename,
                                  final GSFeatureTypeEncoder fte, final GSLayerEncoder layerEncoder) {
        /*
         * This is the equivalent call with cUrl:
         *
         * {@code curl -u admin:geoserver -XPOST -H 'Content-type: text/xml' \ -d
         * "<featureType><name>easia_gaul_1_aggr</name><nativeCRS>EPSG:4326</nativeCRS><enabled>true</enabled></featureType>" \
         * http://localhost:8080/geoserver/rest/workspaces/it.geosolutions/ datastores/pg_kids/featuretypes }
         *
         * and a PUT to <BR> restURL + "/rest/layers/" workspace + : + layerName
         */
        String ftypeXml = fte.toString();
        StringBuilder postUrl = new StringBuilder(restURL).append("/rest/workspaces/")
                .append(workspace).append("/datastores/").append(storename).append("/featuretypes");

        final String layername = fte.getName();
        if (layername == null || layername.isEmpty()) {
            if (LOGGER.isErrorEnabled()) {
                LOGGER.error("GSFeatureTypeEncoder has no valid name associated, try using GSFeatureTypeEncoder.setName(String)");
            }
            return "GSFeatureTypeEncoder has no valid name associated, try using GSFeatureTypeEncoder.setName(String)";
        }

        String configuredResult = HTTPUtils.postXml(postUrl.toString(), ftypeXml, this.gsuser,
                this.gspass);

        boolean published = configuredResult != null;
        boolean configured = false;

        if (!published) {
            LOGGER.warn("Error in publishing (" + configuredResult + ") " + workspace + ":"
                    + storename + "/" + layername);
        } else {
            LOGGER.info("DB layer successfully added (layer:" + layername + ")");

            if (layerEncoder == null) {
                if (LOGGER.isErrorEnabled()) {
                    LOGGER.error("GSLayerEncoder is null: Unable to find the defaultStyle for this layer");
                }
                return "GSLayerEncoder is null: Unable to find the defaultStyle for this layer";
            }

            configured = configureLayer(workspace, layername, layerEncoder);

            if (!configured) {
                LOGGER.warn("Error in configuring (" + configuredResult + ") " + workspace + ":"
                        + storename + "/" + layername);
            } else {
                LOGGER.info("DB layer successfully configured (layer:" + layername + ")");
            }
        }

        return postUrl.toString();
    }
}
